package queue;

import java.util.ArrayList;
import java.util.List;

import util.Globals;

import models.ExtendedCloudlet;

public class PriorityQueue {
	
	private List<ExtendedCloudlet> cloudletList;
	private int maxSize = 0;
	
	public PriorityQueue(){
	}
	
	public void setCloudletList(List<ExtendedCloudlet> cloudletList){
		this.cloudletList = cloudletList;	
		if(Globals.DEBUG_QUEUE)
			System.out.println("[PriorityQueue] Cloudlet list : " + cloudletList.size());
	}
	
	
	/**
	 * gets the next cloudlet to serve wrt the HOL strategy.
	 * 
	 * @pre getCloudletList() ordered ascending by actualSubmitTime
	 * @post $none
	 * 
	 */
	public ExtendedCloudlet getNextCloudlet(double simulatedTime, double priority1, double priority2){
		
		int preferredClass = -1;
		
		if(priority1 > priority2)
			preferredClass = 1;
		if(priority1 < priority2)
			preferredClass = 2;
		
		ArrayList<ExtendedCloudlet> eligibleCloudlets = new ArrayList<ExtendedCloudlet>();
		
		for (ExtendedCloudlet cloudlet : cloudletList) {
			if(cloudlet.getActualSubmitTime() <= simulatedTime)
				eligibleCloudlets.add(cloudlet);
			if(cloudlet.getActualSubmitTime() > simulatedTime)
				break;
		}
		

		
		if(eligibleCloudlets.size() > maxSize){
			maxSize = eligibleCloudlets.size();
		}
				
		if(Globals.DEBUG_QUEUE)
			System.out.println("[PriorityQueue] max size: " + maxSize + " eligible size: " +  eligibleCloudlets.size());
		
		// if no preferred class returns first cloudlet
		if(preferredClass == -1)
			return cloudletList.get(0);
			
		ExtendedCloudlet cloudlet = null;

		for (ExtendedCloudlet eligibleCloudlet : eligibleCloudlets) {
			if(eligibleCloudlet.getClassType() == preferredClass){
				cloudlet = eligibleCloudlet;
				break;
			}
		}
		
		if(cloudlet == null){
			cloudlet = cloudletList.get(0);
		}
		
		return cloudlet;
	}
	
	
	// gets the queue size at a given simulation time
	// works only at runtime not once the simulation ends
	public int getQueueSize(double simulatedTime){
		
		ArrayList<ExtendedCloudlet> eligibleCloudlets = new ArrayList<ExtendedCloudlet>();
		
		for (ExtendedCloudlet cloudlet : cloudletList) {
			if(cloudlet.getActualSubmitTime() <= simulatedTime)
				eligibleCloudlets.add(cloudlet);
			if(cloudlet.getActualSubmitTime() > simulatedTime)
				break;
		}
		
		if(eligibleCloudlets.size() > maxSize)
			maxSize = eligibleCloudlets.size();
		
		if(Globals.DEBUG_QUEUE)
			System.out.println("[PriorityQueue] max size: " + maxSize + " eligible size: " +  eligibleCloudlets.size());
		
		return eligibleCloudlets.size();
	}

	
	// gets the max queue size seen in simulation
	// or et the call instant during the simulation 
	public int getMaxSize() {
		return maxSize;
	}

}
